import ComResUrl from "src/_T/Res/ComResUrl";
import InstanceT from "src/_T/Ts/InstanceT";
import { SetDataProxy } from "../Data/SetDataProxy";
import { EMusics } from "../ResE/EMusics";
import { ESounds } from "../ResE/ESounds";
/**
 * 音效管理类
 */
@InstanceT.DecorateInstance()
export default class AudioManager {
    /** 单例 */
    public static readonly instance: AudioManager;
    //
    private constructor() { }

    //当前播放的bgm
    private m_onBGM: Laya.SoundChannel;

    //当前播放的音效列表
    private m_onSoundList: Map<Laya.SoundChannel, Laya.Vector3> = new Map<Laya.SoundChannel, Laya.Vector3>();
    /**是否失去焦点 */
    static IsLoseFocus: boolean = false;
    private _Camera: Laya.Transform3D;
    public get Camera(): Laya.Transform3D {
        return this._Camera;
    }
    public set Camera(value: Laya.Transform3D) {
        this._Camera = value;
    }

    SoundsDic: number = 20;
    //初始化
    public init() {
        /**设置当失去焦点后是否自动停止音效 */
        Laya.SoundManager.autoStopMusic = false;
        //根据数据设置背景音乐和音效是否静音
        /**失去焦点 */
        Laya.stage.on(Laya.Event.BLUR, this, this.LoseFocus);
        /**获取焦点 */
        Laya.stage.on(Laya.Event.FOCUS, this, this.GetFocus);
        AudioManager.soundMuted = !SetDataProxy.instance.data.ifOpenSound;
        //AudioManager.musicMuted = SetDataProxy.instance.data.ifOpenMusic;
        Laya.timer.frameLoop(5, this, this.UpdateSoundsVolume);
    }

    /**失去焦点 */
    LoseFocus() {
        console.log("失去焦点");
        AudioManager.IsLoseFocus = true;
        AudioManager.soundMuted = true;
        AudioManager.pauseMusic();
        AudioManager.pauseSound();
    }

    /**获取焦点 */
    GetFocus() {
        console.log("获取焦点");
        AudioManager.IsLoseFocus = false;
        //AudioManager.musicMuted = !SetDataProxy.instance.data.ifOpenMusic;
        AudioManager.soundMuted = !SetDataProxy.instance.data.ifOpenSound;
        AudioManager.resumeMusic();
        AudioManager.resumeSound();
    }
    public UpdateSoundsVolume() {
        if (this._Camera) {
            this.m_onSoundList.forEach((Value, Key) => {
                if (Key == null) {
                    this.m_onSoundList.delete(Key);
                }
            })
            this.m_onSoundList.forEach((Value, Key) => {
                this.SetSoundChannelvolumeByWordPos(Value, Key);
            })
        }
    }
    public SetSoundChannelvolumeByWordPos(Value: Laya.Vector3, Key: Laya.SoundChannel) {
        if (Key == null) { return; }
        if (Value != null) {
            let Dic = this.GetTargetDisByWordPos(this._Camera.position.clone(), Value);
            let volume = 0;
            if (Dic >= this.SoundsDic) {
                volume = 0;
            } else {
                volume = 1 - (Dic / this.SoundsDic);
            }
            Key.volume = volume > 1 ? 1 : volume;
        }
    }

    public GetTargetDisByWordPos(LeftPos: Laya.Vector3, RightPos: Laya.Vector3): number {
        if (LeftPos != null && RightPos != null) {
            LeftPos.y = 0;
            RightPos.y = 0;
            return Laya.Vector3.distance(LeftPos, RightPos);
        }
        return 0;
    }

    /**
     * 背景音乐和所有音效是否静音。
     */
    static set muted(value: boolean) {
        Laya.SoundManager.muted = value;
    }
    /**
     * 所有音效（不包括背景音乐）是否静音。
     */
    static set soundMuted(value: boolean) {
        Laya.SoundManager.soundMuted = value;
    }
    /**
     * 背景音乐（不包括音效）是否静音。
     */
    static set musicMuted(value: boolean) {
        Laya.SoundManager.musicMuted = value;
    }
    /**
     * 停止所有音乐
     */
    public static pauseSound() {
        //暂停所有音效
        Laya.SoundManager.stopAllSound();
    }
    /**
     * 音效继续
     */
    public static resumeSound() {
        //继续播放当前播放的音效
        if (!SetDataProxy.instance.data.ifOpenSound) return;
        console.log("音效继续");
        this.instance.m_onSoundList.forEach((Value, Key) => {
            Key && Key.resume();
        });
    }

    /**
     * 暂停背景音乐
     */
    public static pauseMusic() {
        this.instance.m_onBGM && this.instance.m_onBGM.pause();
    }

    /**
     * 继续播放背景音乐
     */
    public static resumeMusic() {
        if (!SetDataProxy.instance.data.ifOpenMusic) return;
        console.log("继续播放背景音乐");
        this.instance.m_onBGM && this.instance.m_onBGM.resume();
    }

    /**
     * 设置音效音量
     * @param _n 音量 0~1
     * @param _url 资源地址
     */
    public static setSoundVolume(_n: number = 1, _url?: string) {
        Laya.SoundManager.setSoundVolume(_n, _url);
    }
    /**
     * 设置背景音乐音量
     * @param _n 音量 0~1
     */
    public static setMusicVolume(_n: number = 1) {
        Laya.SoundManager.setMusicVolume(_n);
    }

    /**
     * 播放音效。音效可以同时播放多个。
     * @param name 音效名字
     * @param loops 循环次数,0表示无限循环。
     * @param complete 声音播放完成回调  Handler对象。
     * @param soundClass 使用哪个声音类进行播放，null表示自动选择。
     * @param startTime 声音播放起始时间。
     * @return SoundChannel对象，通过此对象可以对声音进行控制，以及获取声音信息。
     */
    static playSound(name: ESounds, loops?: number, complete?: Laya.Handler, WordPos: Laya.Vector3 = null, soundClass?: new () => any, startTime?: number): Laya.SoundChannel {
        if (AudioManager.IsLoseFocus) return;
        if (!name) { return; }

        let _sound: Laya.SoundChannel = Laya.SoundManager.playSound(ComResUrl.SoundURL(name), loops, complete, soundClass, startTime);
        if (WordPos != null) { WordPos.y = 0; }
        if (this.instance._Camera != null) {
            this.instance.SetSoundChannelvolumeByWordPos(WordPos, _sound);
        }
        this.instance.m_onSoundList.set(_sound, WordPos);
        return _sound;
    }
    /**
     * 播放背景音乐。背景音乐同时只能播放一个，如果在播放背景音乐时再次调用本方法，会先停止之前的背景音乐，再播放当前的背景音乐。
     * @param name 背景音效名字
     * @param loops 循环次数,0表示无限循环。
     * @param complete 声音播放完成回调,complete 结果参数 true: 播放完成, false/undefined ：stop触发的complete。
     * @param startTime 声音播放起始时间。
     * @return SoundChannel对象，通过此对象可以对声音进行控制，以及获取声音信息。
     */
    ErrorCount = 0;
    static playMusic(name: EMusics, loops?: number, complete?: Laya.Handler, startTime?: number): Laya.SoundChannel {

        if (!name) { return; }
        let _music: Laya.SoundChannel = Laya.SoundManager.playMusic(ComResUrl.MusicURL(name), loops, complete, startTime);
        this.instance.m_onBGM = _music;
        if (!SetDataProxy.instance.data.ifOpenMusic) {
            this.pauseMusic();
        }
        console.log(this.instance.m_onBGM);
        return _music;
    }

    /**
     * 停止音效播放。
     * @param soundsName 音效名字
     */
    static stopSound(soundsName: ESounds): void {
        Laya.SoundManager.stopSound(ComResUrl.SoundURL(soundsName));
    }
    /**
     * 停止背景音效播放。
     * @param musicName 音效名字
     */
    static stopMusic(): void {
        Laya.SoundManager.stopMusic();
    }

}